package action

import scala.swing._
import java.awt.Color
import java.io.File
import java.util.ArrayList
import javax.swing.JOptionPane
import lang.LOC
import parserjc.Evaluator
import parserjc.Compile
import scala.collection.mutable.HashMap
import scala.io._
import parser._
import ewu._
import ewu.expressions.ExpArray
import gui._

/*
 * Diese Klasse erbt von der Action-Klasse und ist fuer die Funktionen des Verify-Menues
 * zustaendig. Hierzu wird ueber das Attribut subAction die jeweilige Aktion aufgerufen.
 * Hier befinden sich somit auch die jeweiligen Parse-Programmteile fuer die verschiedenen
 * Verifikationsfunktionen.
 */

case class MenuVerify(name: String, tt: Layout, subAction: Int) extends Action(name)  {

  def apply() = {
    var tp = tt.getActivProject();
    var fname:Array[String] = new Array(2);
    fname(0) = ""
    fname(1) = ""
    if(tp != null)
      if(tp.maindatei != null)
        fname = tp.maindatei.getName().toLowerCase().split("_");
    if(List(1, 2, 3, 4).contains(subAction)) {
      if(tp == null || fname(0).equals("test") || fname(0).equals("out") ||
         fname(0).equals("prop") || fname(0).equals("trace") || fname(0).equals("proof")) {
        
      }
      else {
        //Modus abfragen/unterscheiden
        Layout.prolamode match {
          case CONST.MODE_ADA =>
            //Mit Parser-Combinator auf Fehlermeldung pruefen
            var t = CheckAda.par(tt.getSelectedTabTopText.toLowerCase)
            //Mit Jaccie-Parser interne Darstellung parsen
            var comp = new Compile()
            comp.setInput(tt.toEvalCase(tt.getSelectedTabTopText.replaceAll("\n"," ")))
            comp.run()

            var eval = new Evaluator(comp.getSICTree)
            var confs:HashMap[String, Konfiguration] = eval.getEWU;
            var haupt:(String, Konfiguration) = confs.headOption match {
              case Some(x) => x
              case None => null
            }

            if(t == false && comp.parsable == false) {
              var err = CheckAda.parError(tt.getSelectedTabTopText.toLowerCase)
              errMsg(err)
            }
            else if(comp.parsable == false) {
              Dialog.showMessage(tt, LOC.get("FehlerCode"), LOC.get("Fehler"),
                                 Dialog.Message.Error)
            }
            else {
              var str = ""
              var filestring = ""
              subAction match {
                //Trace(TestDateiauswahl)
                case 2 =>
                  //Test-File-Abfrage, wenn keine Test-Datei gesetzt
                  var usertestfile = tt.getActivProject.testfile
                  if(usertestfile == null) {
                    var aktordner:File = tt.getActivProject.maindatei.getParentFile
                    var aktpath = aktordner.getAbsolutePath
                    var anderedateien = aktordner.list
                    var testdateien = new ArrayList[String]()
                    for(i <- anderedateien) {
                      var splitted = i.split("_")
                      if(splitted(0).toLowerCase.equals("test") && splitted(1).
                            toLowerCase.equals(eval.hauptprozedurname.toLowerCase)) {
                        testdateien.add(i)
                      }
                    }

                    if(testdateien.size == 0) {
                      Dialog.showMessage(tt, LOC.get("FehlerKeineTestDatei"), 
                                         LOC.get("Fehler"),
                                         Dialog.Message.Info)
                    }
                    else {
                      var usertestfilestring = JOptionPane.showInputDialog(tt.peer,
                                                     LOC.get("TestDateiAuswahlText") + ":",
                                                     LOC.get("TestDateiAuswahl"),
                                                     JOptionPane.QUESTION_MESSAGE, icon,
                                                     testdateien.toArray, null) match {
                        case x:String => x
                        case _ => null
                      }

                      if(usertestfilestring == null || usertestfilestring == "")
                        Dialog.showMessage(tt, LOC.get("FehlerTestDateiAuswahl"), 
                                           LOC.get("Fehler"),
                                           Dialog.Message.Info)
                      else {
                        usertestfile = new File(aktpath + "\\" + usertestfilestring)
                        tt.getActivProject.testfile = usertestfile
                      } 
                    }
                  }
                  if(usertestfile != null) {
                      var usertestfilestring = usertestfile.getName
                      var userfilecontent = scala.io.Source.fromFile(usertestfile).mkString

                      //Mit Parser-Combinator auf Fehlermeldung pruefen
                      var ttest = CheckAda.par(userfilecontent.toLowerCase)
                      //Mit Jaccie-Parser interne Darstellung parsen
                      var comptest = new Compile()
                      comptest.setInput(tt.toEvalCase(userfilecontent.replaceAll("\n"," ")))
                      comptest.run()
                      var evaltest = new Evaluator(comptest.getSICTree)
                      var confstest:HashMap[String, Konfiguration] = evaltest.getEWU
                      var haupttest:(String, Konfiguration) = confstest.headOption match {
                        case Some(x) => x
                        case None => null
                      }
                      if(ttest == false && comptest.parsable == false) {
                        var err = CheckAda.parError(userfilecontent.toLowerCase)
                        errMsg(err)
                      }
                      else if(comptest.parsable == false) {// || haupt == null) {
                        Dialog.showMessage(tt, LOC.get("FehlerCode"), LOC.get("Fehler"),
                                           Dialog.Message.Error)
                      }
                      else {
                        var functions:ArrayList[functionExpression] = evaltest.functionExecutes.
                                                            get(evaltest.hauptprozedurname) match {
                          case Some(x) => x
                          case None => new ArrayList
                        }
                        for(i <- 0 to functions.size-1) {
                          var tmp:functionExpression = functions.get(i) match {
                            case x:functionExpression => x
                            case _ => null
                          }
                          if(tmp != null) {
                            //TODO Arrays werden nicht uebergeben als Parameter, evaluate aendern
                            //auf Option[Expression]?
                            //Parameter der Funktion durchlaufen
                            var testvars = new ArrayList[Expression];
                            for(j <- tmp.params) {
                              var varint:Expression = j.evaluate(haupttest._2.umgebung) match {
                                case Some(x:BigInt) => 
                                  if(x == BigInt(298171879)) {
                                    if(j.isInstanceOf[Name]) {
                                      var tet:Expression = haupttest._2.umgebung.getArray(j.
                                                                        asInstanceOf[Name]) match {
                                        case x:ExpArray => x
                                        case _ => null
                                      }
                                      if(tet == null)
                                        Number(BigInt(0))
                                      else
                                        tet
                                    }
                                    else
                                      Number(BigInt(0))
                                  }
                                  else
                                    Number(x) 
                                case None => Number(BigInt(0))
                              }

                              testvars.add(varint)
                            }
                            //Variablen von zugehoeriger Prozedur laden
                            var allvars = eval.allvars.get(tmp.name) match {
                              case Some(x) => x
                              case None => null
                            }
                            var inputvars = eval.inputvars.get(tmp.name) match {
                              case Some(x) => x
                              case None => null
                            }
                            var outputvars = eval.outputvars.get(tmp.name) match {
                              case Some(x) => x
                              case None => null
                            }
                            var arrayvars = eval.arrayvars.get(tmp.name) match {
                              case Some(x) => x
                              case None => null
                            }
                            var varsrelateoninput = eval.varsrelateoninput.get(tmp.name) match {
                              case Some(x) => x
                              case None => null
                            }
                            //Prozedurenvironment aus packagebody updaten
                            var proz:Konfiguration = confs.get(tmp.name) match {
                              case Some(x) => x
                              case None => null
                            }

                            if(proz != null) {
                              for(j <- 0 to testvars.size-1) {
                                var varint = testvars.get(j)
                                var varname = allvars.get(j) match {
                                  case Some(x) => x
                                  case None => null
                                }
                                if(inputvars.isDefined(varname)) {
                                  proz.umgebung.setValue(varname, varint)

                                  // TODO alle *_anf variablen in den Zusicherungen ersetzen(trace)
                                  if(varint.isInstanceOf[ExpArray]) {
                                    var expa = new ExpArray(varint.asInstanceOf[ExpArray].range)
                                    for(k <- 0 to varint.asInstanceOf[ExpArray].
                                                                               getArray.length-1) {
                                      expa.getArray()(k) = varint.asInstanceOf[ExpArray].
                                                                                      getArray()(k)
                                    }
                                    varint = expa
                                  }
                                  if(proz.umgebung.getValue(varname + "_anf") == Some)
                                    proz.umgebung.setValue(varname + "_anf", varint)
                                  else
                                    proz.umgebung.addValue(varname + "_anf", varint)
                                }
                                else if(outputvars.isDefined(varname) && varint.
                                                                          isInstanceOf[ExpArray]) {
                                  var expa = new ExpArray(varint.asInstanceOf[ExpArray].range)

                                  proz.umgebung.setValue(varname, varint)

                                  // TODO alle *_anf variablen in den Zusicherungen ersetzen(trace)
                                  if(proz.umgebung.getValue(varname + "_anf") == Some)
                                    proz.umgebung.setValue(varname + "_anf", expa)
                                  else
                                    proz.umgebung.addValue(varname + "_anf", expa)
                                }
                              }
                              /*
                               * Falls IN-Variablen, moegliche Relationsinitialisierung
                               * ersetzen
                               */
                              if(!inputvars.equals(null)) {
                                var varsrelated = varsrelateoninput
                                if(varsrelated != null) {
                                  for(i <- varsrelated) {
                                    var evalwert = i._2.evaluate(proz.umgebung) match {
                                      case Some(x:BigInt) => 
                                        if(x == BigInt(298171879)) {
                                          if(i._2.isInstanceOf[Name]) {
                                            var tet:Expression = proz.umgebung.
                                                          getArray(i._2.asInstanceOf[Name]) match {
                                              case x:ExpArray => 
                                                var ret = new ExpArray(x.range)
                                                for(k <- 0 to x.getArray.length-1)
                                                  ret.getArray()(k) = x.getArray()(k)
                                                ret
                                              case _ => null
                                            }
                                            if(tet == null)
                                              Number(BigInt(0))
                                            else
                                              tet
                                          }
                                          else
                                            Number(BigInt(0))
                                        }
                                        else
                                          Number(x) 
                                      case None => Number(BigInt(0))
                                    }
                                    if(evalwert != null)
                                      proz.umgebung.setValue(i._1.name, evalwert)
                                    else
                                      Dialog.showMessage(tt, LOC.get("FehlerDeklaration"),
                                                         LOC.get("Fehler"), Dialog.Message.Error)
                                  }
                                }
                              }
                              proz.numerate(List(1))
                              proz.tabbate(1)
                              str = proz.trace(tt) + "\n"
                            }
                          }
                        }
                      }
                      filestring = usertestfilestring
                    }
                //Numerate, Propagate, Beweisbedarf(Prozedurauswahl)
                case _ =>
                  var zielproc = tt.getActivProject.testproc
                  if(zielproc == null) {
                    zielproc = getTargetProc(eval)
                    tt.getActivProject.testproc = zielproc
                  }
                    
                  if(zielproc != null) {
                    var proz:Konfiguration = confs.get(zielproc) match {
                      case Some(x) => x
                      case None => null
                    }
                    filestring = "_" + eval.hauptprozedurname + "_" + zielproc
                    proz.numerate(List(1))
                    proz.tabbate(1)
                    subAction match {
                      case 1 => 
                        str = proz.toString() + "\n"
                      case 3 => 
                        var proctext = getProcSurround(zielproc, eval, 0)               
                        str = proctext._1 + "\n" + proz.propagate_out() + proctext._2 + "\n"
                      case 4 =>
                        proz.propagate
                        str = proz.protocol + "\n"
                    }
                  }
              }
              if(str != "") {
                // TODO Variablen aus Prozedurdefinitionen stehen schon drin, Variablen
                // aus Anweisungsfolge hinzufügen?
                tt.getActivProject.parsed = true

                tt.getActivProject.setT(subAction, str)
                tt.setTabBotText(subAction-1, str) //tmp.teil.getVariables.toString)
                tt.tabsbot.peer.setSelectedIndex(subAction-1)
                
                tt.getActivProject.saveOutpuToFile(tt, subAction, filestring)
                tt.tabsbot.tabsDesc(0).setText(tt.getActivProject.t1file);
                tt.tabsbot.tabsDesc(1).setText(tt.getActivProject.t2file);
                tt.tabsbot.tabsDesc(2).setText(tt.getActivProject.t3file);
                tt.tabsbot.tabsDesc(3).setText(tt.getActivProject.t4file);
                tt.left = new ScrollTreePane(tt)
                tt.left.repaint
              }
            }
        }
      }      
    }
    else if(List(6,8).contains(subAction)) {
      //Modus abfragen/unterscheiden
          Layout.prolamode match {
            case CONST.MODE_ADA =>
              //Mit Parser-Combinator auf Fehlermeldung pruefen
              tt.toEvalCase(tt.getSelectedTabTopText)
              var t = CheckAda.par(tt.getSelectedTabTopText.toLowerCase)
              //Mit Jaccie-Parser interne Darstellung parsen
              var comp = new Compile()
              comp.setInput(tt.toEvalCase(tt.getSelectedTabTopText.replaceAll("\n"," ")))
              comp.run()

              var eval = new Evaluator(comp.getSICTree)
              var confs:HashMap[String, Konfiguration] = eval.getEWU;
              var haupt:(String, Konfiguration) = confs.headOption match {
                case Some(x) => x
                case None => null
              }

              if(t == false && comp.parsable == false) {
                var err = CheckAda.parError(tt.getSelectedTabTopText.toLowerCase)
                errMsg(err)
              }
              else if(comp.parsable == false) {// || haupt == null) {
                Dialog.showMessage(tt, LOC.get("FehlerCode"), LOC.get("Fehler"),
                                   Dialog.Message.Error)
              }
              else {
                //ZielProzedur abfragen
                var userproc = tt.getActivProject.testproc
                if(userproc == null) {
                  userproc = getTargetProc(eval)
                  tt.getActivProject.testproc = userproc
                }

                if(userproc != null) {
                  subAction match {
                    //Checks erzeugen
                    case 6 => 
                      ////Check-Generierung
                      var actpath = tt.getActivProject.maindatei.getParent
                      var filename = actpath + "\\Checks_" + eval.hauptprozedurname + "_" + 
                                     userproc + ".adb"

                      var tfile = new File(filename)
                      var arrayvars = eval.arrayvars.get(userproc).get
                      var checkprozd = confs.get(userproc).get.toCheckVersion(arrayvars)
                      var checkproz = checkprozd._1
                      var addfuncs = checkprozd._2
                      checkproz.numerate(List(1))
                      checkproz.tabbate(1)
                      var proctext = getProcSurround(userproc, eval, 1, addfuncs)
                      var outtext = proctext._1 + "\n" 
                      outtext += checkproz.propagate_out + proctext._2 + "\n"

                      var newpane = new ScrollTextAreaPane(true){setText(outtext)}
                      tt.tabstop.addTab(tfile.getName, newpane)
                      tt.newProject(tfile.getName, tfile, tt.tabstop, newpane)
                      tt.tabstop.setSelectedIndex(tt.tabstop.peer.getTabCount()-1)
                      var tmp = tt.getActivProject
                      tmp.edited = true
                      tmp.saved = true
                      tmp.parsed = false
                      tmp.tabpane.peer.setTitleAt(tmp.getTabIndex(), "*" + tmp.name)
                      
                    //Test-Datei erzeugen
                    case 8 =>
                      var testindex = 1
                      var testprocname = "Test_" + eval.hauptprozedurname + "_" + userproc + "_" +
                                                                                          testindex
                      var actpath = tt.getActivProject.maindatei.getParent
                      var tfile = new File(actpath + "\\" + testprocname + ".adb")
                      while(tfile.exists || tt.getProjectWithFile(tfile) != null) {
                        testindex += 1
                        testprocname = "Test_" + eval.hauptprozedurname + "_" + userproc + "_" +
                                                                                          testindex
                        tfile = new File(actpath + "\\" + testprocname + ".adb")
                      }

                      var testproc = "WITH " + eval.hauptprozedurname + "; USE " +
                                                                   eval.hauptprozedurname + ";\n\n"
                      testproc += "PROCEDURE " + testprocname + " IS\n"
                      var testprocauf = "   " + userproc + "("

                      var allvars = eval.allvars.get(userproc) match {
                        case Some(x) => x
                        case _ => null
                      }
                      var invars = eval.inputvars.get(userproc) match {
                        case Some(x) => x
                        case _ => null
                      }
                      var outvars = eval.outputvars.get(userproc) match {
                        case Some(x) => x
                        case _ => null
                      }
                      var arrayvars = eval.arrayvars.get(userproc) match {
                        case Some(x) => x
                        case _ => null
                      }
                      if(allvars != null)
                        if(allvars.size > 0) {
                          for(j <- 0 to allvars.size-1) {
                            testproc += "   " + allvars.get(j).get + ": "
                            testprocauf += allvars.get(j).get
                            var vartype = ""
                            var testvartype = ""
                            if(arrayvars.contains(allvars.get(j).get)) {
                              vartype = "IntArray"
                              testvartype = vartype + "(<" + LOC.get("HierTestGrenzeEingabe") + 
                                                ">..<" + LOC.get("HierTestGrenzeEingabe") + ">)"
                            }

                            else {
                              vartype = "Integer"
                              testvartype = "Integer"
                            }   
                            testproc += testvartype
                            if(invars.isDefined(Name(allvars.get(j).get))) {
                              testproc += " := <" + LOC.get("HierTestVarEingabe") + ">"
                            }
                            if(outvars.isDefined(Name(allvars.get(j).get))) {
                            }                       
                            if(j < allvars.size-1) {
                              testprocauf += ", "
                            }
                            testproc += ";\n"
                          }
                          testprocauf += ");\n"

                        }
                      testproc += "BEGIN\n" + testprocauf + "END " + testprocname + ";"
                  
                      var newpane = new ScrollTextAreaPane(true) {
                        setText(testproc)
                      }
                      tt.tabstop.addTab(tfile.getName, newpane)
                      tt.newProject(tfile.getName, tfile, tt.tabstop, newpane)
                      tt.tabstop.setSelectedIndex(tt.tabstop.peer.getTabCount()-1)
                      var tmp = tt.getActivProject
                      tmp.edited = true
                      tmp.saved = true
                      tmp.parsed = false
                      tmp.tabpane.peer.setTitleAt(tmp.getTabIndex(), "*" + tmp.name)
                  }
                }
              }
          }
    }
    else { 
      subAction match {
        //Zu testende Prozedur auswaehlen
        case 10 =>
          var datei = tt.getActivProject.maindatei
          var comp = new Compile()
          var inp = ""
          if(datei.exists)
            inp = scala.io.Source.fromFile(datei).mkString
          comp.setInput(tt.toEvalCase(inp.replaceAll("\n"," ")))
          comp.run()
          var eval = new Evaluator(comp.getSICTree)
          eval.getEWU()
          var zielproc = getTargetProc(eval)
          if(zielproc != null) {
            tt.getActivProject.testproc = zielproc
            tt.getActivProject.loadOutput
            tt.getActivProject.showProject(tt.tabsbot_pane1.textarea, 
                                           tt.tabsbot_pane2.textarea, 
                                           tt.tabsbot_pane3.textarea, 
                                           tt.tabsbot_pane4.textarea)
            tt.tabsbot.tabsDesc(0).setText(tt.getActivProject.t1file);
            tt.tabsbot.tabsDesc(1).setText(tt.getActivProject.t2file);
            tt.tabsbot.tabsDesc(2).setText(tt.getActivProject.t3file);
            tt.tabsbot.tabsDesc(3).setText(tt.getActivProject.t4file);
          }  
        //Test-Datei auswaehlen
        case 11 =>
          var datei = tt.getActivProject.maindatei
          var zielproc = tt.getActivProject.testproc
          //Pruefen, ob eine Prozedur ausgewaehlt wurde zum Testen
          if(zielproc == null) {
            Dialog.showMessage(tt, LOC.get("FehlerProzedurAuswahl"), LOC.get("Fehler"),
                                   Dialog.Message.Error)
          }
          else {
            var usertestfilestring:String = null
            var testfile:File = null
            if(zielproc != null) {
              //Test-File-Abfrage
              var aktordner:File = datei.getParentFile
              var aktpath = aktordner.getAbsolutePath
              var anderedateien = aktordner.list
              var testdateien = new ArrayList[String]()
              for(i <- anderedateien) {
                var splitted = i.split("_")
                if(splitted.length >= 3) {
                  if(splitted(0).toLowerCase.equals("test") && 
                     splitted(1).toLowerCase.equals(datei.getName.replace(".adb","").toLowerCase) &&
                     splitted(2).toLowerCase.equals(zielproc.toLowerCase)
                  ) {
                    testdateien.add(i)
                  }
                } 
              }

              if(testdateien.size == 0) {
                Dialog.showMessage(tt, LOC.get("FehlerKeineTestDatei"), LOC.get("Fehler"),
                                   Dialog.Message.Info)
              }
              else {
                usertestfilestring = JOptionPane.showInputDialog(tt.peer, 
                                           LOC.get("TestDateiAuswahlText") + ":",
                                           LOC.get("TestDateiAuswahl"), 
                                           JOptionPane.QUESTION_MESSAGE, null,
                                           testdateien.toArray, null) match {
                  case x:String => x
                  case _ => null
                }
              }
              if(usertestfilestring != null) {
                usertestfilestring = datei.getParentFile + "\\" + usertestfilestring
                testfile = new File(usertestfilestring)
                tt.getActivProject.testfile = testfile
                tt.getActivProject.loadOutput
                tt.getActivProject.showProject(tt.tabsbot_pane1.textarea, 
                                           tt.tabsbot_pane2.textarea, 
                                           tt.tabsbot_pane3.textarea, 
                                           tt.tabsbot_pane4.textarea)
                tt.tabsbot.tabsDesc(0).setText(tt.getActivProject.t1file);
                tt.tabsbot.tabsDesc(1).setText(tt.getActivProject.t2file);
                tt.tabsbot.tabsDesc(2).setText(tt.getActivProject.t3file);
                tt.tabsbot.tabsDesc(3).setText(tt.getActivProject.t4file);
              } 
            }
          }
        //Ada-WHILE Wechsel
        case 1001 =>
          Layout.prolamode = 0
          tt.toolbar.visible(9, false)
          tt.toolbar.visible(10, true)
          tt.statusBar.setMessage(LOC.get("Modus") + ": Ada")
        
        case 1002 =>
          Layout.prolamode = 1
          tt.toolbar.visible(9, true)
          tt.toolbar.visible(10, false)
          tt.statusBar.setMessage(LOC.get("Modus") + ": WHILE")

        case _ =>
          println("Action3.scala")
      }
    }
  }
  
  
  
  /*
   * gibt die vom User ausgwählte ZielProzedur zurück, sonst null
   */
  def getTargetProc(eval: Evaluator) : String = {
    var confs:HashMap[String, Konfiguration] = eval.conf;
    var procs = new ArrayList[String]

    for(i <- confs) {
      var procstr = i._1
      
      var allvars = eval.allvars.get(i._1) match {
        case Some(x) => x
        case _ => null
      }
      var invars = eval.inputvars.get(i._1) match {
        case Some(x) => x
        case _ => null
      }
      var outvars = eval.outputvars.get(i._1) match {
        case Some(x) => x
        case _ => null
      }
      var arrayvars = eval.arrayvars.get(i._1) match {
        case Some(x) => x
        case _ => null
      }
      if(allvars != null) {
        if(allvars.size > 0) {
          procstr += "("
          for(j <- 0 to allvars.size-1) {
            procstr += allvars.get(j).get + ":"
            var vartype = ""
            if(arrayvars.contains(allvars.get(j).get)) {
              vartype = "IntArray"
            }
            else {
              vartype = "Integer"
            }   
            if(invars.isDefined(Name(allvars.get(j).get))) {
              procstr += " IN"
            }
            if(outvars.isDefined(Name(allvars.get(j).get))) {
              procstr += " OUT"
            }                       
            procstr += " " + vartype
            if(j < allvars.size-1) {
              procstr += "; "
            }
          }
          procstr += ")"

        }
      }
      procs.add(procstr)
    }

    var userproc:String = null
    if(procs.size > 1) {
      userproc = JOptionPane.showInputDialog(tt.peer, LOC.get("ProzedurAuswahlText")+":",
                                               LOC.get("ProzedurAuswahl"),
                                               JOptionPane.QUESTION_MESSAGE, icon,
                                               procs.toArray.reverse.toArray, null) match {
        case x:String => x
        case _ => null
      }
    }
    else if(procs.size == 1) {
      userproc = procs.get(0)
      Dialog.showMessage(tt, LOC.get("InfoEineProzedur"), LOC.get("Info"),
                                   Dialog.Message.Info)
    }
    
    if(userproc != null)
      return userproc.substring(0, userproc.indexOf("("));
    else
      return null
  }
  
  /*
   * gibt den Prozedurrahmen zu einer Prozedur zurück
   */
  def getProcSurround(name: String, eval: Evaluator, mitanf: Int, addfuncs: ArrayList[String] = new ArrayList()) : (String, String) = {
    //Prozedurrahmen erzeugen
    var headtext = "PROCEDURE " + name;
    var optanfvars = ""
    var foottext = "END " + name + ";"
    //Variablen von zugehoeriger Prozedur laden
    var allvars = eval.allvars.get(name) match {
      case Some(x) => x
      case None => null
    }
    var inputvars = eval.inputvars.get(name) match {
      case Some(x) => x
      case None => null
    }
    var outputvars = eval.outputvars.get(name) match {
      case Some(x) => x
      case None => null
    }
    var arrayvars = eval.arrayvars.get(name) match {
      case Some(x) => x
      case None => null
    }
    var varsrelateoninput = eval.varsrelateoninput.get(name) match {
      case Some(x) => x
      case None => null
    }
    if(allvars.size > 0) {
      headtext += " ("
      for(k <- 0 to allvars.size-1) {
        var varname = allvars.get(k).get
        headtext += varname + ": "
        optanfvars += "   " + varname + "_anf: "
        if(inputvars.isDefined(Name(varname)))
          headtext += "IN "
        if(outputvars.isDefined(Name(varname)))
          headtext += "OUT "
        if(arrayvars.contains(varname)) {
          headtext += "IntArray"
          optanfvars += "IntArray := " + varname + ";\n"
        }  
        else {
          headtext += "Integer"
          optanfvars += "Integer := " + varname + ";\n"
        }  
        if(k < allvars.size-1)
          headtext += "; "
      }
      headtext += ")"
    }
    headtext += " IS\n"
    var tm = eval.conf.get(name).get.umgebung.map
    for(k <- tm) {
      if(!inputvars.isDefined(k._1) && !outputvars.isDefined(k._1)) {
        headtext += "   " + k._1 + ": "
        if(arrayvars.contains(k._1))
          headtext += "IntArray"
        else
          headtext += "Integer"
        var tn:Name = null
        if(varsrelateoninput != null)
        tn = varsrelateoninput.get(Name(k._1)) match {
          case Some(x) => x.asInstanceOf[Name]
          case _ => null
        }
        if(tn != null) {                             
          headtext += " := " + tn.name + ";\n" 
        }
        else if(k._2 == null)
          headtext += ";\n"
        else if(k._2.isInstanceOf[Number])
          headtext += " := " + k._2 + ";\n"     
      }                            
    }
    
    if(mitanf == 1)
      headtext += optanfvars
    
    for(i <- 0 to addfuncs.size-1)
      headtext += addfuncs.get(i) + "\n"  

    headtext += "BEGIN"

    return (headtext, foottext)
  }

  def errMsg(err: (String, Int, Int)) : Unit = {
    var errmsg = err match {
      case (x,_,_) => x.replaceAll("\n", " ")
    }
    var errline = err match {
      case (_,x,_) => x
    }
    var errcolumn = err match {
      case (_,_,x) => x
    }

    var pane = tt.tabstop.getActiveComponent match {
      case x:ScrollTextAreaPane => x
      case _ => null
    }
    var textlines = pane.textarea.text.split("\n")
    var errApos = 0
    for(i <- 0 to errline-2) {
      errApos += textlines(i).length
    }
    errApos += (errcolumn-1)

    if (errline == textlines.length && textlines(errline-1).length == (errcolumn-1))
      errApos -= 1

    if(pane != null) {
      pane.textarea.peer.grabFocus()

      pane.textarea.peer.setSelectionColor(Color.RED)
      if(errApos < 0)
        errApos = 0
      pane.textarea.peer.setCaretPosition(errApos)
      pane.textarea.peer.setSelectionStart(errApos)
      pane.textarea.peer.setSelectionEnd(errApos+1)

      if(pane.textarea.peer.getSelectedText != null)
        if(!pane.textarea.peer.getSelectedText.equals("\n"))
          errmsg = errmsg.replaceAll("` '","`" + pane.textarea.peer.getSelectedText + "'")
      Dialog.showMessage(tt, LOC.get("FehlerCode") + " (" + LOC.get("FehlerZeile") + ": " +
                         errline + ", " + LOC.get("FehlerZeichen") + ": " + errcolumn +
                         "):\n" + errmsg, LOC.get("Fehler"), Dialog.Message.Error)
    }
    else            
      Dialog.showMessage(tt, LOC.get("FehlerCode") + " (" + LOC.get("FehlerZeile") + ": " +
                         errline + ", " + LOC.get("FehlerZeichen") + ": " + errcolumn + "):\n"+
                         errmsg, LOC.get("Fehler"), Dialog.Message.Error)
  }
  
}


 